package com.ecarx.vhaltests.Utils;

import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;
import android.util.SparseArray;

import java.util.function.Consumer;

public class CarPropertyEventTester implements CarPropertyManager.CarPropertyEventCallback {
    private static final String TAG = "CAR_PROPERTY_VALUE_EVENT";
    public static final int STS_Active = 0;

    public static final int STS_NotActive = 1;

    public static final int STS_Error = 2;

    public static final int STS_NotAvailable = 3;
    private final Consumer<CarPropertyValue<?>> mConsumerValue;

    private final int mPropId;

    public CarPropertyEventTester(int propid) {
        this(propid, null);
    }

    private final SparseArray<CarPropertyValue<?>> mValues = new SparseArray<>();

    public CarPropertyEventTester(int propid, Consumer<CarPropertyValue<?>> consumer) {
        this.mConsumerValue = consumer;
        this.mPropId = propid;
    }

    @Override
    public void onChangeEvent(CarPropertyValue carPropertyValue) {
        if (mPropId != carPropertyValue.getPropertyId()) return;
        synchronized (mValues) {
            mValues.put(carPropertyValue.getAreaId(), carPropertyValue);
        }
        if (null != mConsumerValue) mConsumerValue.accept(carPropertyValue);
    }

    @Override
    public void onErrorEvent(int i, int i1) {

    }

    public int getLastStatus() {
        synchronized (mValues) {
            return (0 == mValues.size()) ? -1 : mValues.valueAt(0).getStatus();
        }
    }

    public Object getLastValue() {
        synchronized (mValues) {
            return (0 == mValues.size()) ? -1 : mValues.valueAt(0).getValue();
        }
    }

    public CarPropertyValue<?> getPropertyValue(int area) {
        CarPropertyValue<?> tmp = null;
        int retry = 0;
        do {
            synchronized (mValues) {
                tmp = mValues.get(area);
            }
            if (null == tmp) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ignore) {
                }
            } else break;
        } while (20 > ++retry);
        Log.d(TAG, "area=[" + area + "], retry=[" + retry + "]");
        return tmp;
    }

    public int getStatus(int area) {
        CarPropertyValue<?> tmp = getPropertyValue(area);
        if (null == tmp) return -1;
        return tmp.getStatus();
    }

    public Object getValue(int area) {
        CarPropertyValue<?> tmp = getPropertyValue(area);
        if (null == tmp) return null;
        return tmp.getValue();
    }
}
